/*
 *  cl_main.cpp
 *  AOBench
 *
 *  Created by Nickolay Nickolaev on 9/4/09.
 *  Copyright 2009 __MyCompanyName__. All rights reserved.
 *
 */

#include "cl_main.h"
#include "clTestBase.h"


#define DIM_X	256
#define DIM_Y	DIM_X
#define ARRSZ	(DIM_X*DIM_Y*4)

#ifdef USE_GPU
#define CL_DEV		CL_DEVICE_TYPE_GPU
#endif

#ifdef USE_CPU
#define CL_DEV		CL_DEVICE_TYPE_CPU
#endif

#ifndef CL_DEV
#error "Define CPU or GPU"
#endif

float a[DIM_X*DIM_Y];
float b[DIM_X*DIM_Y];

std::string loadProgram(std::string filename);

int
main(void)
{
#if 0	
    try {
		cl::Context context(CL_DEV, 0, NULL, NULL, NULL);
		
		cl::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
		
		std::string progStr(loadProgram("ao.cl"));
		cl::Program::Sources source(1, std::make_pair(progStr.c_str(),progStr.length()));

		cl::Program program = cl::Program(context, source);
		program.build(devices);
		
		cl::Kernel kernel(program, "main", NULL);
		
		//Set arguments		
		cl::Buffer buffer(context,CL_MEM_WRITE_ONLY,ARRSZ,NULL);
		
		//Queue and bind
		cl::CommandQueue queue(context, devices[0], CL_QUEUE_PROFILING_ENABLE, NULL);
		cl::KernelFunctor func = kernel.bind(
											 queue,
											 cl::NDRange(DIM_X,DIM_Y),
											 cl::NDRange(CL_LOCAL_WRK,CL_LOCAL_WRK));
		
		cl::Event event=func(buffer);
		event.wait();
		
		//Now do some statistics - that's all it's about
		{
			cl_ulong _start,_end;
			event.getProfilingInfo(CL_PROFILING_COMMAND_START,&_start);
			event.getProfilingInfo(CL_PROFILING_COMMAND_END,&_end);
			std::cout<<_start<<"->"<<_end<<"="<<(_end-_start)
				<<" ("<<(float)(_end-_start)/(10e+6)<<" msec)"<<std::endl;
		}
    }

    catch (cl::Error err) {
		std::cerr
		<< "ERROR: "
		<< err.what()
		<< "("
		<< err.err()
		<< ")"
		<< std::endl;
    }
#else
	clTestBase test("ao.cl",CL_DEV);
	cl::Buffer buffer(test.getContext(),CL_MEM_WRITE_ONLY,ARRSZ,NULL);
	test.run("main",buffer);

#ifdef _MSC_VER
	{
		char c;
		std::cout<<"Press ENTER";
		std::cin.get(c);
	}
#endif
#endif
    
	return EXIT_SUCCESS;
}

std::string loadProgram(std::string filename){
	
	std::ifstream ifs(filename.c_str());
	
	if(!ifs)
	{
		std::cerr << "Cannot open file '" << filename << "'\n";
		return std::string("");;
	}

	std::ostringstream oss;
	oss << ifs.rdbuf();

	if(!ifs && !ifs.eof())
		std::cerr << "Error reading file '" << filename << "'\n";

	std::string contents(oss.str());
	
	return contents;
}
